from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings


# 将文件存到fstdfs中
class FastDFSStorage(Storage):
    def __init__(self, base_url=None, client_conf=None):
        """
        初始化
        :param base_url: 用于构造图片完整路径使用，图片服务器的域名
        :param client_conf: FastDFS客户端配置文件的路径
        """
        if base_url is None:
            base_url = settings.FDFS_URL
        self.base_url = base_url
        if client_conf is None:
            client_conf = settings.FDFS_CLIENT_CONF
        self.client_conf = client_conf

    def _open(self, name, mode='rb'):
        """
        打开文件时调用
        这个类是进行文件存储的,不会涉及文件打开,但是必须实现,所以pass
        :param name:
        :param mode:
        :return:
        """
        pass

    def _save(self, name, content):
        """
        实现文件的存储
        :param name: 文件名
        :param content: file类型的对象,通过read方法读取文件二进制
        :return:
        """
        client = Fdfs_client(self.client_conf)
        # 利用二进制实现上传
        ret = client.upload_by_buffer(content.read())
        # 判断是否上传成功
        if ret.get('Status') != 'Upload successed.':
            raise Exception('fastdfs upload error')
        file_id = ret.get('Remote file_id')
        # 点击上传图片按钮时自动调用此方法
        # 返回值会自动存储到ImageField字段对应的模型类属性中,并自动同步到数据库
        return file_id

    def exists(self, name):
        # 文件存在,返回true,那么文件不再存储,所以返回false,要保存的name对应的文件不存在,就调用save进行保存
        return False

    def url(self, name):
        """
        返回文件的相对路劲,只有后半段,仍需拼接前边的路径,所以重写,进行拼接
        :return:
        """
        return self.base_url + name
